
package de.justphil.tcg.tcgandroidclient.content;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.justphil.tcg.tcgandroidclient.Storage;
import de.justphil.tcg.tcgandroidclient.util.StringTools;
import de.justphil.tcg.tcgandroidclient.util.TCGLog;
import android.content.UriMatcher;
import android.net.Uri;

public class TCGUM extends UriMatcher {
	
	/* Uri matches */
	public static final int URI_CARD_IMG = 5;
	public static final int URI_PROPERTY_IMG = 10;
	public static final int URI_CARD = 15;
	public static final int URI_CARDS = 20;
	public static final int URI_DECK = 25;
	public static final int URI_DECKS = 30;
	public static final int URI_CARD_INSTANCE = 35;
	public static final int URI_CARD_INSTANCES = 36;
	public static final int URI_CARD_TO_PROPERTIES = 40;
	public static final int URI_DECK_TO_CARDS = 45;
	public static final int URI_DECKS_TO_CARDS = 46;
	/* */
	private final static int WILDCARD = 0;
	/* */
	public TCGUM() {
	
		super(0);
		{
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getCardIMGUri(WILDCARD)),
					URI_CARD_IMG);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getPropertyIMGUri(WILDCARD)),
					URI_PROPERTY_IMG);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getCardUri(WILDCARD)), URI_CARD);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getCardsUri()), URI_CARDS);
			addURI(TCGContentProvider.AUTHORITY,
					withoutAuthority(getCardToPropertiesUri(WILDCARD)), URI_CARD_TO_PROPERTIES);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getDeckUri(WILDCARD, WILDCARD)),
					URI_DECK);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getDecksUri(WILDCARD)), URI_DECKS);
			addURI(TCGContentProvider.AUTHORITY,
					withoutAuthority(getCardInstanceUri(WILDCARD, WILDCARD)), URI_CARD_INSTANCE);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getCardInstancesUri(WILDCARD)),
					URI_CARD_INSTANCES);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getDeckToCardsUri(WILDCARD)),
					URI_DECK_TO_CARDS);
			addURI(TCGContentProvider.AUTHORITY, withoutAuthority(getDecksToCardsUri()),
					URI_DECKS_TO_CARDS);
		}
	}
	
	public static Uri getPropertyIMGUri(int propertyType) {
	
		return getUri("file/" + DH.FOLDER_PROPERTIES, new long[] {
			propertyType });
	}
	
	public static Uri getCardIMGUri(int cardType) {
	
		return getUri("file/" + DH.FOLDER_CARDS, new long[] {
			cardType });
	}
	
	public static Uri getDecksUri(long playerId) {
	
		return getUri(DH.T_DECKS, new long[] {
			playerId });
	}
	
	public static Uri getDeckUri(long playerId, long deckId) {
	
		return getUri(DH.T_DECKS, new long[] {
				playerId, deckId });
	}
	
	public static Uri getCardToPropertiesUri(int cardType) {
	
		return getUri(DH.T_CARDS_TO_PROPERTIES, new long[] {
			cardType });
	}
	
	public static Uri getDeckToCardsUri(long deckId) {
	
		return getUri(DH.T_DECKS_TO_CARDS, new long[] {
			deckId });
	}
	
	public static Uri getDecksToCardsUri() {
	
		return getUri(DH.T_DECKS_TO_CARDS, null);
	}
	
	public static Uri getCardInstanceUri(long playerId, long cardId) {
	
		return getUri(DH.T_CARD_INSTANCES, new long[] {
				playerId, cardId });
	}
	
	public static Uri getCardInstancesUri(long playerId) {
	
		return getUri(DH.T_CARD_INSTANCES, new long[] {
			playerId });
	}
	
	public static Uri getCardUri(int cardType) {
	
		return getUri(DH.T_CARDS, new long[] {
			cardType });
	}
	
	public static Uri getCardsUri() {
	
		return getUri(DH.T_CARDS, null);
	}
	
	public static String getTable(Uri uri) {
	
		String table = null;
		boolean isNumber = false;
		try {
			table = uri.getPathSegments().get(0);
			if (Long.parseLong(table) >= Long.MIN_VALUE) {
				isNumber = true;
			}
		}
		catch (Exception ignored) {
		}
		if (table == null || "#".equals(table) || "".equals(table) || isNumber) {
			throw new IllegalArgumentException("No valid table could be extracted from uri " + uri
					+ "! Table:" + table);
		}
		return table;
	}
	
	public static long getLongId(int index, Uri uri) {
	
		long id;
		try {
			id = getIds(uri)[index];
		}
		catch (Exception e) {
			throw new IllegalArgumentException("Could not get an id from Uri '" + uri
					+ "' for the index " + index + "!");
		}
		return id;
	}
	
	public static int getIntId(int index, Uri uri) {
	
		long id = getLongId(index, uri);
		if (id > Integer.MAX_VALUE || id < Integer.MIN_VALUE) {
			throw new IllegalArgumentException("The requested Integer id is a Long!");
		}
		return (int) id;
	}
	
	private static Uri getUri(String table, long[] ids) {
	
		String uriStr = StringTools.getString(new Object[] {
				"content://", TCGContentProvider.AUTHORITY, "/", table });
		if (ids != null) {
			for (long id : ids) {
				if (id == WILDCARD) {
					uriStr = StringTools.getString(new Object[] {
							uriStr, "/#" });
				}
				else if (id > 0) {
					uriStr = StringTools.getString(new Object[] {
							uriStr, "/", id });
				}
				else {
					throw new IllegalArgumentException("Ids must be == " + WILDCARD
							+ " or > 0! Ids: " + Arrays.toString(ids));
				}
			}
		}
		return Uri.parse(uriStr);
	}
	
	private static String withoutAuthority(Uri uri) {
	
		String uriStr = uri.toString();
		String result = uriStr.replace(StringTools.getString(new Object[] {
				"content://", TCGContentProvider.AUTHORITY, "/" }), "");
		if (result.equals(uriStr)) {
			throw new IllegalArgumentException("The supplyed uri has the wrong authority!");
		}
		return result;
	}
	
	private static long[] getIds(Uri uri) {
	
		List<String> segments = uri.getPathSegments();
		List<Long> idList = new ArrayList<Long>();
		for (String segment : segments) {
			try {
				idList.add(Long.valueOf(segment));
			}
			catch (NumberFormatException ignored) {
			}
		}
		long[] ids = new long[idList.size()];
		for (int i = 0; i < ids.length; i++) {
			ids[i] = idList.get(i);
		}
		return ids;
	}
}
